<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebShell</title>
    <link rel="stylesheet" href="static/xterm/v4.4.0/xterm.css" />
    <style>
        body {
            margin: 0px;
        }
    </style>
</head>
<body>
<div id="terminal"></div>

<script src="static/xterm/v4.4.0/xterm.min.js"></script>
<script src="static/vue/v2.6.12/vue.js"></script>
<script>
    var app = new Vue({
        el: '#terminal',
        data: {
            socketURI: 'ws://' + document.domain + ':' + location.port + '/webssh'
        },
        methods: {
            getConnectInfo() {
                let _self = this;
                let term_size = _self.getTermSize();
                let host_id = {{ host_id }};
                return 'host_id=' + host_id + '&pty_width=' + term_size.cols + '&pty_height=' + term_size.rows
            },
            getTermSize() {
                let init_width = 6;
                let init_height = 35;
                let windows_width = document.documentElement.clientHeight;
                let windows_height = document.documentElement.clientWidth;
                return {
                    cols: Math.floor(windows_width / init_width),
                    rows: Math.floor(windows_height / init_height),
                }
            },
            resizeTerm() {
                let _self = this;
                let term_size = _self.getTermSize();
                let message = {'status': 1, 'data': null, 'cols': term_size.cols, 'rows': term_size.rows};
                let response_data = JSON.stringify(message);
                _self.socket.send(response_data);
            },
            initTerm() {
                let _self = this;
                let element = document.getElementById('terminal');
                let term_size = _self.getTermSize();
                _self.terminal = new Terminal({
                    rendererType: "canvas",
                    cols: term_size.cols,
                    rows: term_size.rows,
                    useStyle: true,
                    fontSize: 18,
                    cursorBlink: true,            // 关标闪烁
                    cursorStyle: "underline",     // 光标样式 'block' | 'underline' | 'bar'
                    scrollback: 100,              // 当行的滚动超过初始值时保留的行视窗，越大回滚能看的内容越多，
                });

                _self.terminal.open(element);
                _self.terminal.focus();
                _self.terminal.onData((data) => {
                    let _self = this;
                    let message = {'status': 0, 'data': data, 'cols': null, 'rows': null};
                    let response_data = JSON.stringify(message);
                    _self.socket.send(response_data);
                });

                //window.addEventListener('resize', this.resizeTerm);
            },
            initSocket() {
                let _self = this;
                _self.socket = new WebSocket(_self.socketURI+"?"+_self.getConnectInfo());
                _self.socket.binaryType = "arraybuffer";
                _self.socketOnClose();
                _self.socketOnOpen();
                _self.socketOnError();
                _self.socketOnMessage();
            },
            socketOnOpen() {
                let _self = this;
                _self.socket.onopen = () => {
                    console.log('连接成功')
                    _self.initTerm()
                }
            },
            socketOnMessage() {
                let _self = this;
                _self.socket.onmessage = (event) => {
                    let data = JSON.parse(event.data);
                    let message = data.message;
                    let status = data.status;
                    if (status === 0) {
                        let _self = this;
                        _self.terminal.write(message)
                    }
                }
            },
            socketOnClose() {
                let _self = this;
                _self.socket.onclose = () => {
                    let _self = this;
                    console.log('close socket')
                    window.removeEventListener('resize', _self.resizeTerm)
                }
            },
            socketOnError() {
                let _self = this;
                _self.socket.onerror = () => {
                    console.log('socket error')
                }
            },
            disableKeyDown() {
                document.onkeydown = function (e) {
                    let evt = window.event || e;
                    let code = evt.keyCode || evt.which;
                    if ((code == 112) || (code == 113) || (code == 114) || (code == 115) || (code == 116) || (code == 117) ||
                        (code == 118) || (code == 119) || (code == 120) || (code == 121) || (code == 122) || (code == 123)) {
                        evt.keyCode = 0;
                        evt.returnValue = false;
                    }
                }
            },
            disableContextMenu() {
                document.oncontextmenu = function (e) {
                    return false;
                };
            }
        },
        mounted() {
            let _self = this;
            _self.initSocket()
            _self.disableKeyDown()
            _self.disableContextMenu()
        },
        beforeDestroy() {
            let _self = this;
            _self.socket.close()
            _self.terminal.dispose()
        },
    })
</script>
</body>
  </html>